﻿#region Using Directives

    using System;
    using System.Text;

    using Csla;
    using Csla.Data;
    using Csla.Reflection;
    using Csla.Server;

    using MarketPulse.BusinessLogic.Core.System;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Class summary
    /// </summary>
    public class ContactDetailsFactory : ObjectFactory
    {
        #region Member Variables

            /// <summary>
            /// Property that stores the name of the class.
            /// </summary>
            private static readonly Type mClass = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;

            /// <summary>
            /// Property that stores the log4net logger for this class.
            /// </summary>
            private static readonly log4net.ILog mLog = log4net.LogManager.GetLogger(mClass);

        #endregion

        #region Methods

            #region Create Methods

                /// <summary>
                /// Method used to create and return a new ContactDetails object instance
                /// </summary>
                /// <returns>The newly created ContactDetails object</returns>
                [RunLocal]
                public ContactDetails Create()
                {
                    // Create a new instance of the object
                    var contactDetails = (ContactDetails)MethodCaller.CreateInstance(typeof(ContactDetails));

                    contactDetails.Obsolete = false;

                    // Mark it as a new object
                    MarkNew(contactDetails);

                    //Check the business rules for this object
                    CheckRules(contactDetails);

                    return contactDetails;
                }

            #endregion

            #region Fetch Methods

                /// <summary>
                /// Method used to retrieve the ContactDetails for a given User
                /// </summary>
                /// <param name="userGUID">The User to retrieve ContactDetails for</param>
                /// <returns>A valid (populated) ContactDetails object</returns>
                public ContactDetails Fetch(SingleCriteria<Guid> userGUID)
                {
                    using (var manager = ContextManager<DataContextObjects.Production.MUM_dev>.GetManager(Database.BusinessSystem))
                    {
                        var contactDetails = (ContactDetails)MethodCaller.CreateInstance(typeof(ContactDetails));

                        try
                        {
                            var contactDetailsResult = manager.DataContext.UspContactDetailsSelectByUserGUID(userGUID.Value);

                            //TODO refactor at some point to enable the retrieval for more than one set of contact details for a specific user
                            foreach (var tempContactDetails in contactDetailsResult)
                            {
                                // Common properties inherited from MarketPulseBase<ApplicationProfile>
                                LoadProperty(contactDetails, ContactDetails.GUIDProperty, tempContactDetails.ContactDetailsGUID.Value);
                                LoadProperty(contactDetails, ContactDetails.ObsoleteProperty, tempContactDetails.Obsolete.Value);
                                LoadProperty(contactDetails, ContactDetails.InsertUserGUIDProperty, tempContactDetails.InsertUserGUID.Value);
                                LoadProperty(contactDetails, ContactDetails.InsertDateTimeProperty, (SmartDate)tempContactDetails.InsertDateTime);
                                LoadProperty(contactDetails, ContactDetails.UpdateUserGUIDProperty, tempContactDetails.UpdateUserGUID.Value);
                                LoadProperty(contactDetails, ContactDetails.UpdateDateTimeProperty, (SmartDate)tempContactDetails.UpdateDateTime);
                                // Other properties
                                LoadProperty(contactDetails, ContactDetails.AddressLine1Property, tempContactDetails.AddressLine1);
                                LoadProperty(contactDetails, ContactDetails.AddressLine2Property, tempContactDetails.AddressLine2);
                                LoadProperty(contactDetails, ContactDetails.AddressLine3Property, tempContactDetails.AddressLine3);
                                LoadProperty(contactDetails, ContactDetails.AddressLine4Property, tempContactDetails.AddressLine4);
                                LoadProperty(contactDetails, ContactDetails.AddressLine5Property, tempContactDetails.AddressLine5);
                                LoadProperty(contactDetails, ContactDetails.ContactDetailsLabelProperty, tempContactDetails.ContactDetailsLabel);
                                LoadProperty(contactDetails, ContactDetails.ApartmentOrFloorNumberProperty, tempContactDetails.ApartmentOrFloorNumber);
                                LoadProperty(contactDetails, ContactDetails.HouseNameOrNumberProperty, tempContactDetails.HouseNameOrNumber);
                                LoadProperty(contactDetails, ContactDetails.PostCodeProperty, tempContactDetails.PostCode);
                                LoadProperty(contactDetails, ContactDetails.PhoneProperty, tempContactDetails.Phone);
                                LoadProperty(contactDetails, ContactDetails.LatitudeProperty, (float)tempContactDetails.Latitude.Value);
                                LoadProperty(contactDetails, ContactDetails.LongtitudeProperty, (float)tempContactDetails.Longtitude.Value);

                                if (tempContactDetails.CountryGUID.HasValue)
                                {
                                    LoadProperty(contactDetails, ContactDetails.CountryGUIDProperty, tempContactDetails.CountryGUID.Value);
                                }

                                if (tempContactDetails.AreaGUID.HasValue)
                                {
                                    LoadProperty(contactDetails, ContactDetails.AreaGUIDProperty, tempContactDetails.AreaGUID.Value);
                                }

                                // Make sure that CSLA thinks this hasn't changed since being instantiated
                                MarkOld(contactDetails);
                            }
                        }
                        catch (InvalidOperationException ioe)
                        {
                            // Construct error message
                            StringBuilder errorMessage = new StringBuilder();
                            errorMessage.Append("Unable to locate exactly one set of Contact Details for the UserGUID = [ ");
                            errorMessage.Append(userGUID);
                            errorMessage.Append(" ]");
                            mLog.Error(errorMessage.ToString(), ioe);
                        }

                        return contactDetails;
                    }
                }

            #endregion

        #endregion
    }
}
